package network;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Hashtable;
import java.io.InputStreamReader;

import org.json.JSONException;
import org.json.JSONObject;

import core.Card;
import core.Constructable;
import core.Game;
import core.Location;
import core.Player;
import core.Resource;
import core.ResourceType;
/**
 * The client-side proxy for a game object, but treat it as any game. It will forward
 * messages which will be received and parsed by NetworkPlayer, which will call the appropriate
 * methods on the LocalGame object.
 * @author CodyS
 *
 */
public class NetworkGame extends Game implements Messager {
	private Socket connect;
	private BufferedReader reader;
	private PrintWriter writer;
	private Player p;
	public NetworkGame(Socket s) {
		connect = s;
		try {
			reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
			writer = new PrintWriter(s.getOutputStream());
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		
	}
	public JSONObject makeMessage(String command) {
		JSONObject jo = new JSONObject();
		try {
			jo.put("command", command);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return jo;
	}
	@Override
	/**
	 * Tell the server that this player is ready.
	 */
	public void playerReady(Player p) {
		send(makeMessage("ready"));
	}

	@Override
	/**
	 * Call this with the LocalPlayer after it has been instantiated so that it can receive
	 * messages from this class.
	 */
	public void addPlayer(Player p) {
		this.p = p;
		Thread t = new Thread(new NetworkListener(this,reader));
		t.start();
	}

	@Override
	public void removePlayer(Player p) {
		p.leave();
	}
	/**
	 * Sends a message to the server, which will be received by NetworkPlayer
	 */
	public void send(String message) {
		writer.println(message);
		writer.flush();
	}
	/**
	 * Parses a message and calls the appropriate method on the Player
	 */
	
	public void build(Constructable c, Location l) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void endTurn() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void loseCards(Hashtable<ResourceType, Integer> lose) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void moveRobber(Location l) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void offerTrade(Player seeker,
			Hashtable<ResourceType, Integer> offer,
			Hashtable<ResourceType, Integer> receive) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void playCard(Card c) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void rollDice() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void steal(Player take, Player stealfrom) {
		JSONObject jo = makeMessage("steal");
		try {
			
		} catch(Exception e) {
			
		}
	}
	@Override
	public void receive(JSONObject j) {
		try {
			String command = j.getString("command");
			if (command.equals("turn"))
				p.doTurn();
			else if (command.equals("ready"))
				p.ready();
			else if (command.equals("got card")) {
				String gotCard = j.getString("card");
			}
			else if (command.equals("discard"))
				p.loseCards();
			else if (command.equals("move robber"))
				p.notifyRobber();
			else if (command.equals("choose steal"))
				p.notifySteal();
			else if (command.equals("trade offer")) {
				Hashtable<ResourceType, Integer> offer = (Hashtable<ResourceType, Integer>) j.get("offer");
				Hashtable<ResourceType, Integer> ret = (Hashtable<ResourceType, Integer>) j.get("ret");
				p.notifyTrade(offer, ret);
			}
			else if (command.equals("lost card")) {
				JSONObject card = (JSONObject) j.get("card");
				// convert JSONObject to a card object, then:
				// p.removeCard(card);
			}
			else if (command.equals("lost resource")) {
				String type = j.getString("type");
				int number = j.getInt("number");
			}
			else if (command.equals("update")) { // FIGURE THIS OUT
				JSONObject game = (JSONObject) j.get("game"); // LocalGame
				ArrayList<Card> cards = (ArrayList<Card>) j.get("cards");
				Hashtable<ResourceType,Integer> resources = (Hashtable<ResourceType,Integer>) j.get("resources");
			}
			
		} catch (JSONException e) {
			e.printStackTrace();
		}
		
	}
	@Override
	public void send(JSONObject j) {
		send(j);
	}
	@Override
	public void addToCounter(int add) {
		System.err.println("MORON, YOU BROKE IT.");
		System.exit(0);
	}
	@Override
	public void buildPoint(Constructable c, Location l) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void buildRoad(Constructable c, Location l1, Location l2) {
		// TODO Auto-generated method stub
		
	}
}